小编典典

如何正确继承 dict 并覆盖 __getitem__ 和 __setitem__

all

我正在调试一些代码,我想找出访问特定字典的时间。好吧,它实际上是一个子类化dict并实现了一些额外功能的类。无论如何,我想做的是将dict自己子类化并添加覆盖__getitem____setitem__产生一些调试输出。现在,我有

class DictWatch(dict):
    def __init__(self, *args):
        dict.__init__(self, args)

    def __getitem__(self, key):
        val = dict.__getitem__(self, key)
        log.info("GET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val)))
        return val

    def __setitem__(self, key, val):
        log.info("SET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val)))
        dict.__setitem__(self, key, val)

'name_label'是一个最终将被设置的键,我想用它来识别输出。然后,我将要检测的类更改为子类DictWatch,而不是dict更改对超构造函数的调用。不过,似乎什么都没有发生。我以为我很聪明,但我想知道我是否应该转向不同的方向。

谢谢您的帮助!


阅读 139

收藏
2022-05-22

共1个答案

小编典典

子类化的另一个问题dict是内置__init__不调用update,内置update不调用__setitem__。因此,如果您希望所有 setitem 操作都通过您的__setitem__函数,您应该确保它被自己调用:

class DictWatch(dict):
    def __init__(self, *args, **kwargs):
        self.update(*args, **kwargs)

    def __getitem__(self, key):
        val = dict.__getitem__(self, key)
        print('GET', key)
        return val

    def __setitem__(self, key, val):
        print('SET', key, val)
        dict.__setitem__(self, key, val)

    def __repr__(self):
        dictrepr = dict.__repr__(self)
        return '%s(%s)' % (type(self).__name__, dictrepr)

    def update(self, *args, **kwargs):
        print('update', args, kwargs)
        for k, v in dict(*args, **kwargs).iteritems():
            self[k] = v
2022-05-22